from Util.mongodb import MongodbUtils
from Common.com_func import is_null, log, mongo_exception_send_DD
from Env import env_config as cfg
from pymongo.errors import ServerSelectionTimeoutError


class db_model(object):

    def __init__(self, table, error_msg, pro_name=""):
        self.pro_name = pro_name    # 项目名称
        self.table = table          # 数据表名
        self.error_msg = error_msg  # 错误信息
        self.ip = cfg.MONGODB_ADDR            # 数据库地址
        self.database = cfg.MONGODB_DATABASE  # 数据库
        self.collection = pro_name + table    # 数据库集合

    def db_config(func):
        def wrap(self, *args, **kwargs):
            with MongodbUtils(ip=self.ip, database=self.database, collection=self.collection) as pro_db:
                try:
                    return func(self=self, pro_db=pro_db, *args, **kwargs)
                except Exception as e:
                    mongo_exception_send_DD(e=e, msg=self.error_msg + " (" + self.pro_name + ")")
                    return "mongo error"
        return wrap

    @db_config
    def query_db(self, filter=None, query=None, is_many=True, is_cursor=False, pro_db=None):
        """
            查 询
             <入参>  filter：    过滤需要返回的字段 -> {"name": 1, "_id": 0}  不返回 _id 字段, 只返回 name 字段
                    is_cursor： 是否返回游标类型
             <返回>  单条：Dict
                    多条：List | Curosr
        """
        if is_many:
            all_cursor = pro_db.find(query, filter)
            return is_cursor and all_cursor or list(all_cursor)
        else:
            one_res_dict = pro_db.find_one(query, filter)
            return one_res_dict != None and one_res_dict or {}

    @db_config
    def insert_db(self, data, is_many=True, pro_db=None):
        """ 新 增  data:（ 单条：字典 | 多条：列表 ）"""
        is_many and pro_db.insert_many(data) or pro_db.insert_one(data)

    @db_config
    def delete_db(self, query=None, is_many=True, pro_db=None):
        """ 删 除 """
        is_many and pro_db.delete_many(query) or pro_db.delete_one(query)

    @db_config
    def update_db(self, set_dict, query=None, is_many=True, pro_db=None):
        """ 修 改 """
        query = query and query or {}
        is_many and pro_db.update_many(query, {"$set": set_dict}) or pro_db.update_one(query, {"$set": set_dict})

    @db_config
    def pip_aggregate(self, pipline, pro_db=None):
        """ 聚 合 查 询 """
        return list(pro_db.aggregate(pipline, allowDiskUse=True))


if __name__ == '__main__':

    pro_name = "pro_demo_1"
    # dm = db_model(pro_name='pro_demo_1', table=cfg.TABLE_CASE, error_msg="统计项目用例")
    # # 查询多条
    # query = {"request_method": "GET"}
    # filter = {"_id": 0}
    # all_case_list = dm.query_db()
    # print(all_case_list)
    # print(len(all_case_list))
    # # 查询一条
    # res_dict = dm.query_db(query=query, filter=filter, is_many=False)
    # print(res_dict)

    # 聚合查询
    # dm = db_model(pro_name='pro_demo_1', table=cfg.TABLE_RESULT, error_msg="聚合查询")
    # pipline = []
    # pipline.append({"$group": {"_id": "$update_time", "case_num": {"$sum": 1}, "更新时间": {"$first": "$update_time"}}})
    # pipline.append({"$sort": {"更新时间": -1}})
    # res = dm.pip_aggregate(pipline=pipline)
    # print(res)
    # print(type(res))

    # 分组查询 ( _id 为必填的分组字段 )
    # pipline = []
    # pipline.append({"$group": {"_id": "$update_time", "case_num": {"$sum": 1}, "更新时间": {"$first": "$update_time"}}})
    # pipline.append({"$sort": {"更新时间": -1}})
    # dm = db_model(pro_name='pro_demo_1', table=cfg.TABLE_RESULT, error_msg="获取测试时间列表")
    # result_list = dm.pip_aggregate(pipline=pipline)
    # print(list(map(lambda x: x.get("更新时间"), result_list)))

    # 查询 关联 接口
    dm = db_model(pro_name=pro_name, table=cfg.TABLE_CASE, error_msg="获取用例搜索结果")
    filter_dict = {"interface_name": 1, "_id": 0}
    query_dict = {"$or": [{"upstream_relation_case": {"$ne": ""}}, {"downstream_relation_field_name_list": {"$ne": []}}]}
    results = dm.query_db(filter=filter_dict, query=query_dict)
    for e in results:
        print(e)


